// SysY 词法分析器主程序
//
// 这是 r9cc 编译器项目的词法分析器实现
// 支持完整的 SysY 语言词法规范，包括：
// - 关键字、运算符、分隔符识别
// - 标识符和各种进制数字常量处理
// - 注释忽略和错误报告

use std::{env, fs, process};

mod lexer;
use lexer::tokenize;

/// 程序主入口点
///
/// 处理命令行参数，读取源文件，执行词法分析，并输出结果
fn main() {
    // 解析命令行参数
    let args: Vec<String> = env::args().collect();

    // 验证参数数量
    if args.len() != 2 {
        eprintln!("Usage: {} <filename>", args[0]);
        process::exit(1);
    }

    let filename = &args[1];

    // 读取源文件内容
    let input = match read_source_file(filename) {
        Ok(content) => content,
        Err(error_msg) => {
            eprintln!("{error_msg}");
            process::exit(1);
        }
    };

    // 执行词法分析并输出结果
    perform_lexical_analysis(&input);
}

/// 安全地读取源文件内容
///
/// # 参数
/// * `filename` - 要读取的文件路径
///
/// # 返回值
/// * `Ok(String)` - 成功时返回文件内容
/// * `Err(String)` - 失败时返回错误描述
fn read_source_file(filename: &str) -> Result<String, String> {
    fs::read_to_string(filename).map_err(|e| format!("Failed to read file '{filename}': {e}"))
}

/// 执行词法分析并输出结果到标准错误
///
/// 根据分析结果输出 Token 信息或错误信息
/// 所有输出都通过标准错误流进行，符合 SysY 规范要求
///
/// # 参数
/// * `input` - 要分析的源代码字符串
fn perform_lexical_analysis(input: &str) {
    match tokenize(input) {
        Ok(tokens) => {
            // 输出所有识别到的 Token
            for token in tokens {
                eprintln!("{}", token.format_output());
            }
        }
        Err(errors) => {
            // 输出所有词法错误
            for error in errors {
                eprintln!("{}", error.format_output());
            }
        }
    }
}
